/* 
 * File:   PsoParticle.h
 * Author: jcrada
 *
 * Created on April 8, 2009, 7:43 PM
 */

#ifndef _PSOPARTICLE_H
#define	_PSOPARTICLE_H

#include <string>
#include <QtXml/QDomElement>
#include <QtXml/QDomDocument>
#include <assert.h>

namespace jcrada {

    class PsoParticle {
    public:

        enum eSpace {
            S_CONTINUOUS = 0, S_DISCRETE, S_COUNT
        };
    private:
        int _size;

        double* _velocity;
        double* _max_velocity;
        double* _position;
        double* _min_position;
        double* _max_position;
        eSpace* _space;
        double* _pbest;
        double* _nbest;

        double _inertia;
        double _fitness;

        double _fitness_nbest;
        double _fitness_pbest;

    public:

        PsoParticle( int size );
        virtual ~PsoParticle( );
        virtual PsoParticle* clone( ) const;
        virtual std::string toString( ) const;
        virtual std::string toString( const double * component ) const;

        virtual void setMaxVelocity( double value );
        virtual void setMinPosition( double value );
        virtual void setMaxPosition( double value );
        virtual void setSpace( eSpace space );

        static PsoParticle* fromXml( const QDomElement& xml, bool* ok );
        virtual void toXml( QDomDocument& xml, QDomElement* parent = NULL ) const;

        virtual int getSize( ) const {
            return this->_size;
        }

        virtual double getFitness( ) const {
            return this->_fitness;
        }

        virtual void setFitness( double fitness ) {
            this->_fitness = fitness;
        }

        virtual double getInertia( ) const {
            return this->_inertia;
        }

        virtual void setInertia( double inertia ) {
            this->_inertia = inertia;
        }

        virtual double getFitnessForPersonalBest( ) const {
            return this->_fitness_pbest;
        }

        virtual void setFitnessForPersonalBest( double fitness ) {
            this->_fitness_pbest = fitness;
        }

        virtual double getFitnessForNeighborhoodBest( ) const {
            return this->_fitness_nbest;
        }

        virtual void setFitnessForNeighborhoodBest( double fitness ) {
            this->_fitness_nbest = fitness;
        }

        virtual double* getVelocity( ) const {
            return this->_velocity;
        }

        virtual double getVelocity( int index ) const {
            assert(index >= 0 && index < getSize());
            return this->_velocity[index];
        }

        virtual void setVelocity( int index, double value ) {
            assert(index >= 0 && index < getSize());
            this->_velocity[index] = value;
        }

        virtual double getMaxVelocity( int index ) const {
            assert(index >= 0 && index < getSize());
            return this->_max_velocity[index];
        }

        virtual void setMaxVelocity( int index, double value ) {
            assert(index >= 0 && index < getSize());
            this->_max_velocity[index] = value;
        }

        virtual double* getPosition( ) const {
            return this->_position;
        }

        virtual double getPosition( int index ) const {
            assert(index >= 0 && index < getSize());
            return this->_position[index];
        }

        virtual void setPosition( int index, double value ) {
            assert(index >= 0 && index < getSize());
            this->_position[index] = value;
        }

        virtual double getMinPosition( int index ) const {
            assert(index >= 0 && index < getSize());
            return this->_min_position[index];
        }

        virtual void setMinPosition( int index, double value ) {
            assert(index >= 0 && index < getSize());
            this->_min_position[index] = value;
        }

        virtual double getMaxPosition( int index ) const {
            assert(index >= 0 && index < getSize());
            return this->_max_position[index];
        }

        virtual void setMaxPosition( int index, double value ) {
            assert(index >= 0 && index < getSize());
            this->_max_position[index] = value;
        }

        virtual eSpace getSpace( int index ) const {
            assert(index >= 0 && index < getSize());
            return this->_space[index];
        }

        virtual void setSpace( int index, eSpace space ) {
            assert(index >= 0 && index < getSize());
            this->_space[index] = space;
        }

        virtual double* getBestPersonalPosition( ) const {
            return this->_pbest;
        }

        virtual void setBestPersonalPosition( const double* position ) {
            for (int i = 0; i < getSize(); ++i) {
                setBestPersonalPosition(i, position[i]);
            }
        }

        virtual double getBestPersonalPosition( int index ) const {
            assert(index >= 0 && index < getSize());
            return this->_pbest[index];
        }

        virtual void setBestPersonalPosition( int index, double value ) {
            assert(index >= 0 && index < getSize());
            this->_pbest[index] = value;
        }

        virtual double* getBestNeighborhoodPosition( ) const {
            return this->_nbest;
        }

        virtual void setBestNeighborhoodPosition( const double* position ) {
            for (int i = 0; i < getSize(); ++i) {
                setBestNeighborhoodPosition(i, position[i]);
            }
        }

        virtual double getBestNeighborhoodPosition( int index ) const {
            assert(index >= 0 && index < getSize());
            return this->_nbest[index];
        }

        virtual void setBestNeighborhoodPosition( int index, double value ) {
            assert(index >= 0 && index < getSize());
            this->_nbest[index] = value;
        }

    };
}

#endif	/* _PSOPARTICLE_H */

